package com.fuhailiu.opengl.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.ContentResolver;
import android.net.Uri;
import android.text.format.DateFormat;

public class FileUtil {

	public static boolean isVideoFile(String fileName) {
		String ext = fileName.substring(fileName.lastIndexOf('.'));
		if (ext.equals(".3gp") || ext.equals(".mp4")) {
			return true;
		}
		return false;
	}

	public static String makeFileName(String path, String prefix, String suffix) {
		if (null == path) {
			return null;
		}
		if (!path.endsWith(File.separator)) {
			path = path + File.separator;
		}
		String strDate = DateFormat.format("yyyyMMddkkmmss", System.currentTimeMillis()).toString();
		String filename = path + prefix + strDate + suffix;
		int index = 0;
		File file = new File(filename);
		while (file.exists()) {
			index++;
			filename = path + prefix + strDate + "_" + index + suffix;
			file = new File(filename);
		}
		return filename;
	}

	public static boolean isFileOrDirectoryExist(String fileName) {
		if (fileName == null)
			return false;
		boolean res = false;
		File file = new File(fileName);
		if (file.exists()) {
			res = true;
		}
		file = null;
		return res;
	}

	public static boolean createDirectory(String path) {
		if (path == null)
			return false;
		File file = new File(path);
		if (!file.exists()) {
			file.getParentFile().mkdirs();
			file.mkdirs();
			return true;
		} else {
			return false;
		}
	}

	public static boolean createEmptyFile(String path) {
		if (null == path) {
			return false;
		}
		File file = new File(path);
		if (!file.exists()) {
			if (file.isDirectory()) {
				return false;
			}
			file.getParentFile().mkdirs();
			try {
				new File(file.getParent(), file.getName()).createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
			return true;
		} else {
			return false;
		}
	}

	public static boolean copyFile(ContentResolver cr, Uri fromUri, String toFilePath) {
		if (null == cr || null == fromUri || null == toFilePath) {
			return false;
		}
		File toFile = null;
		try {
			toFile = new File(toFilePath);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		if (!toFile.getParentFile().exists()) {
			toFile.getParentFile().mkdirs();
		}
		if (toFile.exists()) {
			toFile.delete();
		}
		try {
			InputStream is = cr.openInputStream(fromUri);
			FileOutputStream fos = new FileOutputStream(toFilePath);
			byte[] buffer = new byte[1024];
			int count;
			while ((count = is.read(buffer)) != -1) {
				fos.write(buffer, 0, count);
			}
			is.close();
			fos.flush();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	public static boolean copyFile(String fromFilePath, String toFilePath) {
		File fromFile = null;
		File toFile = null;
		try {
			fromFile = new File(fromFilePath);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		try {
			toFile = new File(toFilePath);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		if (!fromFile.exists()) {
			return false;
		}
		if (!fromFile.isFile()) {
			return false;
		}
		if (!fromFile.canRead()) {
			return false;
		}
		if (!toFile.getParentFile().exists()) {
			toFile.getParentFile().mkdirs();
		}
		if (toFile.exists()) {
			toFile.delete();
		}
		try {
			FileInputStream fis = new FileInputStream(fromFile);
			FileOutputStream fos = new FileOutputStream(toFile);
			int count;
			byte buffer[] = new byte[1024];
			while ((count = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, count);
			}
			fis.close();
			fos.flush();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	public static boolean copyDirectory(String srcDirName, String destDirName) {
		// 判断源目录是否存在
		File srcDir = new File(srcDirName);
		if (!srcDir.exists()) {
			return false;
		} else if (!srcDir.isDirectory()) {
			return false;
		}

		// 如果目标目录名不是以文件分隔符结尾，则加上文件分隔符
		if (!destDirName.endsWith(File.separator)) {
			destDirName = destDirName + File.separator;
		}
		File destDir = new File(destDirName);
		// 如果目标文件夹存在
		if (destDir.exists()) {
			new File(destDirName).delete();
		} else {
			// 创建目的目录
			if (!destDir.mkdirs()) {
				return false;
			}
		}

		boolean success = false;
		File[] files = srcDir.listFiles();
		for (int i = 0; i < files.length; i++) {
			// 复制文件
			if (files[i].isFile()) {
				success = copyFile(files[i].getAbsolutePath(), destDirName + files[i].getName());
				if (!success)
					break;
			} else if (files[i].isDirectory()) {
				success = copyDirectory(files[i].getAbsolutePath(), destDirName + files[i].getName());
				if (!success)
					break;
			}
		}
		if (!success) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean replaceFileWithRegex(String fileName, String patternString, String newValue) {
		boolean success = true;

		File file = new File(fileName);
		BufferedReader in = null;
		PrintWriter out = null;

		try {
			in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			success = false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			success = false;
		}

		File outfile = new File(file + ".tmp");
		try {
			out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), "utf-8")));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			success = false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			success = false;
		}

		Pattern pattern = Pattern.compile(patternString);
		Matcher matcher = null;
		String line;
		try {
			while ((line = in.readLine()) != null) {
				matcher = pattern.matcher(line);
				if (null != matcher && matcher.find()) {
					String result = matcher.group(1);
					if (null != result) {
						out.println(line.replace(result, newValue));
					} else {
						out.println(line);
					}
				} else {
					out.println(line);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			success = false;
		}

		if (null != out) {
			out.close();
		}
		if (null != in) {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
				success = false;
			}
		}

		if (null != file) {
			file.delete();
		}
		if (null != outfile) {
			outfile.renameTo(file);
		}
		return success;
	}

	private static void replaceFile(String fileName, String srcString, String dstString) throws IOException, UnsupportedEncodingException {
		File file = new File(fileName);
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
		File outfile = new File(file + ".tmp");
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), "utf-8")));
		String line;
		while ((line = in.readLine()) != null) {
			out.println(line.replaceAll(srcString, dstString));
		}
		out.close();
		in.close();
		file.delete();
		outfile.renameTo(file);
	}

	public static boolean replaceDirectory(String path, String srcString, String dstString) {
		File file = new File(path);
		File[] files = file.listFiles();
		for (File subFile : files) {
			// 处理目录
			if (subFile.isDirectory()) {
				replaceDirectory(subFile.getAbsolutePath(), srcString, dstString);
			}
			// 处理文件
			else {
				try {
					replaceFile(subFile.getAbsolutePath(), srcString, dstString);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					return false;
				} catch (IOException e) {
					e.printStackTrace();
					return false;
				}
			}
		}
		return true;
	}

	public static boolean replaceToNewFile(String srcFile, String dstFile, String[] srcString, String[] dstString) {
		if (null == srcFile || null == dstFile || null == srcString || null == dstString || srcString.length != dstString.length) {
			return false;
		}

		boolean bSuccess = true;

		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(new FileInputStream(new File(srcFile)), "utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			bSuccess = false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			bSuccess = false;
		}

		if (!bSuccess) {
			try {
				if (null != in) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return bSuccess;
		}

		File outfile = new File(dstFile);
		PrintWriter out = null;
		try {
			out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), "utf-8")));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			bSuccess = false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			bSuccess = false;
		}

		if (!bSuccess) {
			try {
				if (null != out) {
					out.close();
				}
				if (null != in) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return bSuccess;
		}

		String line;
		int len = srcString.length;

		try {
			while ((line = in.readLine()) != null) {
				for (int i = 0; i < len; i++) {
					if (line.contains(srcString[i])) {
						line = line.replaceAll(srcString[i], dstString[i]);
					}
				}
				out.println(line);
			}
		} catch (IOException e1) {
			e1.printStackTrace();
			return false;
		}

		out.close();
		try {
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return bSuccess;
	}

	public static void deleteFileOrDirectory(String path) {
		if (path == null)
			return;
		File file = new File(path);
		if (file.exists()) {
			if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					deleteFileOrDirectory(files[i].getAbsolutePath());
				}
			}
			file.delete();
		}
	}

	public static String getExtension(String filePath) {
		if (null == filePath || filePath.isEmpty()) {
			return null;
		}

		int i = filePath.lastIndexOf('.');
		if (i >= 0 && i < (filePath.length() - 1)) {
			return filePath.substring(i + 1);
		}

		return null;
	}

	public static boolean rename(String filaname, String newFileName) {
		if (null == filaname || null == newFileName || filaname.isEmpty() || newFileName.isEmpty()) {
			return false;
		}
		File file = new File(filaname);
		if (file.exists()) {
			file.renameTo(new File(newFileName));
			return true;
		} else {
			return false;
		}
	}

	public static byte[] getByteArrayFromFile(String fileName) {
		File file = null;
		try {
			file = new File(fileName);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		if (!file.exists() || !file.isFile() || !file.canRead()) {
			return null;
		}

		byte[] byteArray = null;

		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			int count;
			byte buffer[] = new byte[1024];
			while ((count = fis.read(buffer)) > 0) {
				baos.write(buffer, 0, count);
			}
			byteArray = baos.toByteArray();
			fis.close();
			baos.flush();
			baos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return byteArray;
	}

	public static boolean saveByteArrayToFile(String fileName, byte[] data) {
		boolean success = false;
		if (null != fileName) {
			String name = fileName;
			int count = 0;
			File file = new File(name);
			while (file.exists()) {
				count++;
				name = fileName + count;
				file = new File(name);
			}
			file.getParentFile().mkdirs();
			try {
				FileOutputStream fs = new FileOutputStream(fileName);
				fs.write(data);
				fs.close();
				success = true;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return success;
		} else {
			return success;
		}
	}

}
